package com.hulk.dryad.activiti7.service.impl;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.hulk.dryad.persistence.entity.ActTask;
import com.hulk.dryad.persistence.entity.ActWorkflowFormData;
import com.hulk.dryad.persistence.entity.ActWorkflowFormDataModel;
import com.hulk.dryad.activiti7.service.IActTaskService;
import com.hulk.dryad.activiti7.service.IActWorkflowFormDataService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.FormProperty;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hulk
 */
@Slf4j
@AllArgsConstructor
@Service
public class ActTaskServiceImpl implements IActTaskService {


	private RepositoryService repositoryService;
	private RuntimeService runtimeService;
	private TaskRuntime taskRuntime;

	private IActWorkflowFormDataService actWorkflowFormDataService;


	@Override
	public ActTask geTask(String taskID) {
		Task task = taskRuntime.task(taskID);
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
		return new ActTask(task, processInstance);
	}

	@Override
	public Page<ActTask> getPageTask(Page page) {
		//查询当前登录人和候选人的所有任务
		org.activiti.api.runtime.shared.query.Page<Task> pageTasks = taskRuntime.tasks(Pageable.of((int) ((page.getCurrent() - 1) * page.getSize()), (int) page.getSize()));
		List<Task> tasks = pageTasks.getContent();
		int totalItems = pageTasks.getTotalItems();
		page.setTotal(totalItems);
		if (totalItems != 0) {
			Set<String> processInstanceIdIds = tasks.parallelStream().map(t -> t.getProcessInstanceId()).collect(Collectors.toSet());
			List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list();
			List<ActTask> actTasks = tasks.stream()
					.map(t -> new ActTask(t, processInstanceList.parallelStream().filter(pi -> t.getProcessInstanceId().equals(pi.getId())).findAny().get()))
					.collect(Collectors.toList());
			page.setRecords(actTasks);
		}
		return page;
	}

	@Override
	public Task completeTask(String taskId, Map<String, Object> variables) {

		Task task = taskRuntime.task(taskId);
		if (task.getAssignee() == null) {
			taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
		}
		Task tk = taskRuntime.complete(
				TaskPayloadBuilder.complete().withTaskId(task.getId()).withVariables(variables)
				.build());
		return tk;
	}


	@Override
	public List<ActWorkflowFormDataModel> formDataShow(String taskID) {
		Task task = taskRuntime.task(taskID);
			/*
			------------------------------------------------------------------------------
            FormProperty_0ueitp2--__!!类型--__!!LABLE名称--__!!是否参数--__!!LABLE默认值
            例子：
            FormProperty_3qipis2--__!!radio--__!!审批意见--__!!i--__!!同意--__--不同意 (备注：单选钮描述用--__-- 分隔符分隔)
            FormProperty_0lffpcm--__!!textarea--__!!批注--__!!f__!!null

            默认值：无、字符常量、FormProperty_开头定义过的控件ID（判断默认值开头是FormProperty_ 就是之前表单存过的值，取出来放在默认值上）
            是否参数：f为不是参数，s是字符，t是时间(不需要int，因为这里int等价于string)
            注：类型是可以获取到的，但是为了统一配置原则，都配置到
            ------------------------------------------------------------------------------
            */

		List<ActWorkflowFormData> ActWorkflowFormDatas = actWorkflowFormDataService.selectActWorkflowFormDataByBusinessKey(task.getBusinessKey());

		//注意!!!!!!!!:表单Key必须要任务编号一模一样，因为参数需要任务key，但是无法获取，只能获取表单key“task.getFormKey()”当做任务key
		UserTask userTask = (UserTask) repositoryService.getBpmnModel(task.getProcessDefinitionId())
				.getFlowElement(task.getFormKey());
		if (userTask == null) {
			return null;
		}
		List<FormProperty> formProperties = userTask.getFormProperties();
		List<String> collects = formProperties.stream().map(fp -> fp.getId()).collect(Collectors.toList());

		List<ActWorkflowFormDataModel> collectList = Lists.newArrayList();
		for (String collect : collects) {
			List<String> li = Splitter.on("--__!!").omitEmptyStrings().trimResults().splitToList(collect);
			ActWorkflowFormDataModel model = new ActWorkflowFormDataModel();
			model.setControlId(li.get(0));
			model.setControlType(li.get(1));
			model.setControlLable(li.get(2));
			model.setControlIsParam(li.get(3));

			model.setControlDefault(null);
			model.setControlValue(null);
			if ("radio".equals(model.getControlType())) {
				model.setControlDefault(li.get(4));
			}

//		    String controlValue = li.get(4);
//			//默认值如果是表单控件ID
//			if (controlValue.startsWith("FormProperty_")) {
//				boolean containsFlag =false;
//				ActWorkflowFormData formData = null;
//				for (ActWorkflowFormData form : ActWorkflowFormDatas){
//					if (Objects.equals(form.getControlId(),controlValue)){
//						containsFlag = true ;
//						formData = form;
//						break;
//					}
//				}
//				if(containsFlag){
//					//控件ID存在
//					model.setControlValue(formData.getControlValue());
//				}else {
//					//控件ID不存在
//					log.error("读取失败，检查" + controlValue + "配置");
//					model.setControlValue("读取失败，检查" + controlValue + "配置");
//				}
//			} else {
//				//默认值如果不是表单控件ID则写入默认值
//				model.setControlValue(controlValue);
//			}
			collectList.add(model);
		}
		return collectList;
	}

	@Override
	public int formDataSave(String taskID, List<ActWorkflowFormDataModel> awfs) {
		Task task = taskRuntime.task(taskID);
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
		//没有任何参数
		Boolean hasVariables = false;
		HashMap<String, Object> variables = new HashMap<String, Object>();
		//前端传来的字符串，拆分成每个控件
		List<ActWorkflowFormData> acwfds = new ArrayList<>();
		for (ActWorkflowFormDataModel awf : awfs) {
			ActWorkflowFormData actWorkflowFormData = new ActWorkflowFormData(processInstance.getBusinessKey(), awf, task);
			acwfds.add(actWorkflowFormData);
			//构建参数集合
			if (!"f".equals(awf.getControlIsParam())) {
				variables.put(awf.getControlId(), awf.getControlValue());
				hasVariables = true;
			}else {
				log.info("ControlId: [{}], controlValue: [{}], 控件值不作为参数.", awf.getControlId(), awf.getControlValue());
			}
		}//for结束
		if (task.getAssignee() == null) {
			taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
		}
		if (hasVariables) {
			//带参数完成任务
			taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID)
					.withVariables(variables)
					.build());
		} else {
			taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(taskID)
					.build());
		}
		//写入数据库
		return actWorkflowFormDataService.insertActWorkflowFormDatas(acwfds);
	}
}
